package com.atguigu.tingshu.album.task;

import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author NJG
 * @version 1.0
 * @date 2025/7/30 16:49
 * @description 布隆过滤器的扩容和重建
 */
@Slf4j
@Component

public class RebuildBloomFilterTask {
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private AlbumInfoService albumInfoService;


    @Scheduled(cron = "0 0 2 1 * ? ")
//    @Scheduled(cron = "0/5 * * * * ? ")
    public void rebuildBloomFilter() {
        //1.获取现有的布隆数据 :期望值,误判率,预估值
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER);
        if (bloomFilter.isExists()) {
            long expectedInsertions = bloomFilter.getExpectedInsertions();
            double falseProbability = bloomFilter.getFalseProbability();
            long count = bloomFilter.count();
            if (count > expectedInsertions) {
                log.info("布隆过滤器扩容开始,当前布隆过滤器信息:期望值:{},误判率:{},已插入数据:{}", expectedInsertions, falseProbability, count);
                RBloomFilter<Object> newBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER + ":new");
                if (!newBloomFilter.isExists()) {
                    newBloomFilter.tryInit(expectedInsertions * 2, falseProbability);
                    //2.将合法数据添加到新的布隆过滤器
                    List<AlbumInfo> albumInfoList = albumInfoService.list(new LambdaQueryWrapper<AlbumInfo>()
                            .eq(AlbumInfo::getStatus, SystemConstant.ALBUM_STATUS_PASS)
                            .select(AlbumInfo::getId));
                    albumInfoList.forEach(albumInfo -> newBloomFilter.add(albumInfo.getId()));
                    log.info("布隆过滤器扩容完成,当前布隆过滤器信息:期望值:{},误判率:{},已插入数据:{}", expectedInsertions, falseProbability, count);
                    //3.将新的布隆过滤器替换旧的布隆过滤器
                    //3.1删除旧的布隆过滤器
                    bloomFilter.delete();
                    //3.2将新的布隆过滤器重命名为旧的布隆过滤器
                    newBloomFilter.rename(RedisConstant.ALBUM_BLOOM_FILTER);
                }
            } else {
                log.info("布隆过滤器重建开始,当前布隆过滤器信息:期望值:{},误判率:{},已插入数据:{}", expectedInsertions, falseProbability, count);
                RBloomFilter<Object> newBloomFilter = redissonClient.getBloomFilter(RedisConstant.ALBUM_BLOOM_FILTER + ":new");
                if (!newBloomFilter.isExists()) {
                    newBloomFilter.tryInit(expectedInsertions, falseProbability);
                    //2.将合法数据添加到新的布隆过滤器
                    List<AlbumInfo> albumInfoList = albumInfoService.list(new LambdaQueryWrapper<AlbumInfo>()
                            .eq(AlbumInfo::getStatus, SystemConstant.ALBUM_STATUS_PASS)
                            .select(AlbumInfo::getId));
                    albumInfoList.forEach(albumInfo -> newBloomFilter.add(albumInfo.getId()));
                    //3.将新的布隆过滤器替换旧的布隆过滤器
                    //3.1删除旧的布隆过滤器
                    bloomFilter.delete();
                    //3.2将新的布隆过滤器重命名为旧的布隆过滤器
                    newBloomFilter.rename(RedisConstant.ALBUM_BLOOM_FILTER);
                }
            }
        }
    }
}